<!DOCTPYE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
html, body {
  margin: 0;
}

#container > div {
  font-size: 10px;
  width: 5ch;
  border: thin solid black;
}
</style>
<div id="log"></div>
<div id="container">
  <div id="normal-wrap">0123 456</div>
  <div id="normal-wrap-with-overflow-space">01234 567</div>
  <div id="pre-wrap" style="white-space: pre-wrap">0123 45678</div>
  <div id="pre-wrap-with-overflow-space" style="white-space: pre-wrap">01234 5678</div>
  <div id="break-word" style="word-wrap: break-word">0123456789</div>
  <div id="pre" style="white-space:pre">a
b<span></span>b</div>
</div>
<script>
testEmptyBoundsEqualFirstRect('normal-wrap', 4);
testEmptyBoundsEqualFirstRect('normal-wrap-with-overflow-space', 5);

testUniqueRectAt('pre-wrap', 3);
testUniqueRectAt('pre-wrap', 4);
testUniqueRectAt('pre-wrap', 5);

testUniqueRectAt('pre-wrap-with-overflow-space', 4);
testUniqueRectAt('pre-wrap-with-overflow-space', 5);
testUniqueRectAt('pre-wrap-with-overflow-space', 6);

testUniqueRectAt('break-word', 4);
testUniqueRectAt('break-word', 5);

testUniqueRectAt('pre', 0);
testUniqueRectAt('pre', 1);
testUniqueRectAt('pre', 2);

function getRectsAndBoundsAt(id, offset) {
  const element = document.getElementById(id);
  const node = element.firstChild;
  const range = document.createRange();
  range.setStart(node, offset);
  range.setEnd(node, offset + 1);
  return {rects: range.getClientRects(), bounds: range.getBoundingClientRect()}
}

function testEmptyBoundsEqualFirstRect(id, offset) {
  const rectsAndBounds = getRectsAndBoundsAt(id, offset);
  const rects = rectsAndBounds.rects;
  const bounds = rectsAndBounds.bounds;

  // All rects are empty, and bounds should be equal to rects[0].
  test(() => {
    assert_equals(bounds.width, 0);
    assert_greater_than(rects.length, 0);
    assert_equals_rect(bounds, rects[0]);
  }, `${id}[${offset}]: ${rectToString(bounds)} should be equal to the first of ${rectsToString(rects)}`);
}

function testUniqueRectAt(id, offset) {
  test(() => assert_equals(getRectsAndBoundsAt(id, offset).rects.length, 1),
       `${id}[${offset}]: Only one unique client rect`);
}

function assert_equals_rect(actual, expected) {
  for (let prop in expected)
    assert_equals(actual[prop], expected[prop]);
}
function rectsToString(rects) {
  return '[' + Array.prototype.map.call(rects, rectToString).join() + ']';
}

function rectToString(r) {
  return '(' + r.left + ',' + r.top + '-' + r.width + ',' + r.height + ')';
}
</script>
